#include "Server.hpp"
#include <functional>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>       // For fcntl()
#include <sys/socket.h>  // For setsockopt()
#include <netinet/tcp.h> // For TCP_NODELAY
#include <cstring> // For memset()

// 在Server类定义之后添加工具函数实现
namespace {
    // 设置套接字非阻塞模式
    int setSocketNonBlocking(int fd) {
        int flags = fcntl(fd, F_GETFL, 0);
        if (flags == -1) return -1;
        return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
    }

    // 设置TCP_NODELAY选项（禁用Nagle算法）
    void setSocketNodelay(int fd) {
        int enable = 1;
        setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable));
    }

    // 创建监听套接字（三合一函数）
    int socket_bind_listen(int port) {
        if (port < 1024 || port > 65535) return -1;

        // 创建套接字
        int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
        if (listen_fd == -1) {
            perror("socket");
            return -1;
        }

        // 设置地址重用
        int optval = 1;
        if (setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) {
            close(listen_fd);
            return -1;
        }

        // 绑定端口
        sockaddr_in server_addr{};
        server_addr.sin_family = AF_INET;
        server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
        server_addr.sin_port = htons(port);
        if (bind(listen_fd, (sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
            perror("bind");
            close(listen_fd);
            return -1;
        }

        // 开始监听
        if (listen(listen_fd, SOMAXCONN) < 0) {
            perror("listen");
            close(listen_fd);
            return -1;
        }
        return listen_fd;
    }
} // 匿名命名空间结束

Server::Server(int thread_num, int port) :
    threadNum_(thread_num),           // 线程池工作线程数量
    port_(port),                     // 初始化监听端口号
    started_(false),                 // 服务器启动状态标识
    isEventHandling_(false),        // 事件处理状态标识
    isLooping_(false),               // 事件循环状态标识
    isQuit_(false),                  // 退出标志
    clientsServed_(0)                    // 客户端连接数
{
    listenFd_ = socket_bind_listen(port_); // 创建监听套接字并绑定端口
    // 添加错误检查
    if (listenFd_ < 0) {
        LOG << "Failed to create listen socket";
        abort();
    }
    // 设置监听套接字为非阻塞模式（ET模式必须设置）
    if (setSocketNonBlocking(listenFd_) < 0) {
        perror("set socket nonblock failed");
        abort();  // 初始化失败直接终止程序
    }

    acceptChannel_ = std::make_shared<Channel>(listenFd_);
    acceptChannel_->setEvents(EPOLLIN | EPOLLET);
    acceptChannel_->set_read_handler(std::bind(&Server::handNewConn, this));
    // 错误事件处理
    acceptChannel_->set_error_handler([this]() {
        perror("Accept channel error");
        this->stop_loop(); // 停止服务器
        });

    poller_ = std::make_shared<Poller>(); // 初始化poller_
    poller_->epoll_add(acceptChannel_);   // 添加监听套接字到epoll实例


    eventLoopThreadPool_ = std::make_shared<EventLoopThreadPool>(thread_num); // 创建IO线程池
    eventLoopThreadPool_->start(); // 启动IO线程池
    started_ = true; // 服务器初始化完成
}

void Server::start_loop() {
    assert(started_ == true);
    while (!isQuit_.load()) {
        // 1、epoll_wait阻塞 等待就绪事件
        std::vector<ChannelPtr> active_channels;
        poller_->poll(active_channels);
        isEventHandling_ = true;
        // 2、处理每个就绪事件(不同channel绑定了不同的callback)
        for (auto& channel : active_channels) {
            if (channel->getFd() >= 0) {  // 增加有效性检查
                channel->handleEvents();
            }
        }
        isEventHandling_ = false;

    }
    // 退出时清理
    LOG << "mainLoop stop looping";
    isLooping_.store(false);
    eventLoopThreadPool_->stop();    // 停止IO线程池并释放资源
}

void Server::handNewConn() {

    struct sockaddr_in client_addr;
    socklen_t client_addr_len = sizeof(client_addr);
    int client_fd = 0;
    while (true) { // ET模式循环
        client_addr_len = sizeof(client_addr);
        client_fd = accept(listenFd_, (struct sockaddr*)&client_addr, &client_addr_len);
        if (client_fd > 0) {

            // auto tp1 = std::chrono::high_resolution_clock::now();
            // 增加客户端连接计数
            clientsServed_.fetch_add(1);
            LOG << "client_fd: " << client_fd << " has connected. clientsServed_: " << clientsServed_.load();
            // 从线程池获取下一个事件循环
            sp_EventLoop nextLoop = eventLoopThreadPool_->getNextLoop();

            // 设置新连接为非阻塞
            if (setSocketNonBlocking(client_fd) < 0) {
                LOG << "Set non block failed!";
                // perror("Set non block failed!");
                return;
            }
            setSocketNodelay(client_fd);

            // 创建简单回显处理器
            // ChannelPtr clientChannel = ChannelPool::instance().acquire(client_fd);
            ChannelPtr clientChannel = std::make_shared<Channel>(client_fd);
            clientChannel->setEvents(EPOLLIN | EPOLLET);

            // ****** 添加读事件回调 ******
            clientChannel->set_read_handler([clientChannel, nextLoop]() {

                // auto start = std::chrono::high_resolution_clock::now();

                char rbuf[2048];
                static thread_local std::string received_data;
                static thread_local std::string response;
                static bool is_first = true;
                if (is_first) {
                    is_first = false;
                    // 预留空间，避免频繁扩容
                    received_data.reserve(8192);
                    response.reserve(8192);
                }

                received_data.clear(); // 清空接收缓冲区
                response.clear(); // 清空响应缓冲区

                int client_fd = clientChannel->getFd();
                LOG << "client_Channel's read_handler is called. fd: " << client_fd;
                while (true) { // ET模式需要循环读取
                    ssize_t recv_size = read(client_fd, rbuf, sizeof(rbuf));
                    if (recv_size > 0) {
                        received_data.append(rbuf, recv_size);
                    }
                    else if (recv_size == 0) {
                        // 对端正常关闭 (FIN)
                        nextLoop->removeChannel(clientChannel);
                        // ChannelPool::instance().release(clientChannel);
                        clientChannel->closeChannel(); // 关闭 fd
                        break;
                    }
                    else if (recv_size == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
                        // ET 模式下读完数据，正常返回。
                        response = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: "
                            + std::to_string(received_data.size()) + "\r\n\r\n" + received_data;
                        write(client_fd, response.c_str(), response.size());
                        break;
                    }
                    else {
                        // 处理其他错误
                        nextLoop->removeChannel(clientChannel);
                        // ChannelPool::instance().release(clientChannel);
                        clientChannel->closeChannel(); // 关闭 fd
                        break;
                    }
                }

                // auto end = std::chrono::high_resolution_clock::now();
                // auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
                // std::cout << "clientChannel->read_handler 运行耗时: " << duration << "μs" << std::endl;

                });


            // ****** 添加错误事件回调 ******
            clientChannel->set_error_handler([clientChannel, nextLoop]() {
                LOG << "Connection error on fd: " << clientChannel->getFd() << " errno: " << errno;
                // 执行与 read_handler 中错误/关闭路径相同的清理逻辑
                nextLoop->removeChannel(clientChannel); // 从 Poller 移除
                // ChannelPool::instance().release(clientChannel);
                clientChannel->closeChannel(); // 关闭 fd
                });

            // auto tp2 = std::chrono::high_resolution_clock::now();
            // 跨线程注册到目标EventLoop（关键点）
            nextLoop->queueInPendingFunctions([nextLoop, clientChannel]() {
                nextLoop->addChannel(clientChannel); // 确保在IO线程执行
                });

            // auto tp3 = std::chrono::high_resolution_clock::now();
            // auto duration1 = std::chrono::duration_cast<std::chrono::microseconds>(tp2 - tp1).count();
            // auto duration2 = std::chrono::duration_cast<std::chrono::microseconds>(tp3 - tp2).count();
            // std::cout << "acceptChannel->handNewConn() 处理一个新连接耗时: " << duration1 << "μs  跨线程注册到目标EventLoop" << "[Thread " + nextLoop->getLoopId() + "] " << "耗时: " << duration2 << "μs" << std::endl;

        }
        else {
            if (errno == EAGAIN || errno == EWOULDBLOCK) {
                LOG << "Accept later";
                break; // 正常结束循环
            }
            else if (errno == ECONNABORTED || errno == EPROTO) {
                LOG << "Connection error: " << errno;
                continue; // 可恢复错误
            }
            else {
                LOG << "Critical accept error";
                abort();
            }
        }

    }

}
